package kode.boot.logging;

import lombok.Data;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.security.Principal;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;

/**
 * LoggingInfo
 *
 * @author Stark
 * @date 2018/12/15
 */
@Data
public class LoggingInfo implements Serializable {

	private static final long serialVersionUID = 6040667193817973581L;

	/** 编号 */
	private String id;

	/**
	 * 日志信息
	 *
	 * @see Logging#before()
	 */
	private String logBefore;

	/**
	 * 日志信息
	 *
	 * @see Logging#after()
	 */
	private String logAfter;
	/**
	 * 详细
	 *
	 * @see Logging#details()
	 */
	private String[] details;

	/** 最终处理请求的类 */
	private Class<?> target;

	/** 最终调用的方法 */
	private Method method;

	/** 调用方法参数 */
	private Map<String, Object> methodParameters;

	/** 当前登陆的用户 */
	private Principal principal;

	/** 请求 ip */
	private String ip;

	/** 请求地址 */
	private String url;

	/** http method， get/post/put 等等 */
	private String httpMethod;

	/** http 头 */
	private Map<String, String> httpHeaders;

	/** 方法返回结果 */
	private Object result;

	/** 调用出错时的异常 */
	private Throwable exception;

	/** 请求时刻 */
	private long requestTime;

	/** 响应时刻 */
	private long responseTime;

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("LoggingInfo { id='").append(id).append("',\n");
		if (Objects.equals(logBefore, logAfter)) {
			builder.append("log='").append(logBefore).append("',\n");
		} else {
			if (logBefore != null && !"".equals(logBefore)) {
				builder.append("logBefore='").append(logBefore).append("',\n");
			}
			if (logAfter != null && !"".equals(logAfter)) {
				builder.append("logAfter='").append(logAfter).append("',\n");
			}
		}

		if (details != null && details.length != 0) {
			builder.append("details='").append(Arrays.toString(details)).append("',\n");
		}
		builder.append("httpMethod='").append(httpMethod).append("',\n");
		builder.append("request='").append(ip).append(" -> ").append(url).append("',\n");
		builder.append("invoked='").append(target.getName()).append("#").append(method.getName()).append("',\n");
		if (principal != null) {
			builder.append("principal='").append(principal).append("',\n");
		}
		builder.append("methodParams='").append(methodParameters).append("',\n");
		if (result != null) {
			builder.append("result='").append(result).append("',\n");
		}
		if (exception != null) {
			builder.append("exception='").append(exception).append("',\n");
		}
		if (responseTime != 0) {
			builder.append("elapsed='").append((responseTime - requestTime) / 1000.0).append(" s' }");
		}

		return builder.toString();
	}
}
